TypeScript 2.1

    在ES2015中,如果构造函数返回一个对象,那么对于任何super(...)的调用者将隐式地替换掉this的值。因此,有必要获取任何可能的super(...)的返回值并用this进行替换。

    示例

    定义一个类C

    将生成如下代码:

    1. var C = (function (_super) {
    2. __extends(C, _super);
    3. function C() {
    4. var _this = _super.call(this) || this;
    5. _this.a = 0;
    6. return _this;
    7. }
    8. return C;
    9. }(B));

    注意:

    • _super.call(this)存入局部变量_this
    • 构造函数体里所有使用this的地方都被替换为super调用的返回值(例如_this
    • 每个构造函数将明确地返回它的this,以确保正确的继承

    值得注意的是在super(...)调用前就使用thisTypeScript 1.8开始将会引发错误。

    继承内置类型如ErrorArrayMap将是无效的

    做为将this的值替换为super(...)调用返回值的一部分,子类化Error,等的结果可以是非预料的。这是因为ErrorArray等的构造函数会使用ECMAScript 6的new.target来调整它们的原型链;然而,在ECMAScript 5中调用构造函数时却没有有效的方法来确保new.target的值。在默认情况下,其它低级别的编译器也普遍存在这个限制。

    示例

    针对如下的子类:

    1. class FooError extends Error {
    2. super(m);
    3. }
    4. sayHello() {
    5. return "hello " + this.message;
    6. }
    7. }

    你会发现:

    • 由这个子类构造出来的对象上的方法可能为undefined,因此调用sayHello会引发错误。
    • instanceof应用于子类与其实例之前会失效,因此(new FooError()) instanceof FooError会返回false

    做为一个推荐,你可以在任何super(...)调用后立即手动地调整原型。

    1. class FooError extends Error {
    2. constructor(m: string) {
    3. super(m);
    4. // Set the prototype explicitly.
    5. Object.setPrototypeOf(this, FooError.prototype);
    6. }
    7. sayHello() {
    8. return "hello " + this.message;
    9. }
    10. }

    但是,任何FooError的子类也必须要手动地设置原型。对于那些不支持Object.setPrototypeOf的运行时环境,你可以使用。

    不幸的是,这些变通方法在IE10及其之前的版本.aspx)你可以手动地将方法从原型上拷贝到实例上(比如从FooError.prototypethis),但是原型链却是无法修复的。

    默认情况下,const声明和readonly属性不会被推断成字符串,数字,布尔和枚举字面量类型。这意味着你的变量/属性可能具有比之前更细的类型。这将体现在使用===!==的时候。

    示例

    推荐

    针对故意要求更加宽泛类型的情况下,将类型转换成基础类型:

      不对函数和类表达式里捕获的变量进行类型细化

      当泛型类型参数具有stringnumberboolean约束时,会被推断为字符串,数字和布尔字面量类型。此外,如果字面量类型有相同的基础类型(如string),当没有字面量类型做为推断的最佳超类型时这个规则会失效。

      示例

      1. declare function push<T extends string>(...args: T[]): T;
      2. var x = push("A", "B", "C"); // 推断成 "A" | "B" | "C" 在TS 2.1, 在TS 2.0里为 string

      推荐

      1. var x = push<string>("A", "B", "C"); // x是string

      在之前编译器默默地赋予callback(下面的c)的参数一个any类型。原因关乎到编译器如何解析重载的函数表达式。从TypeScript 2.1开始,在使用--noImplicitAny时,这会触发一个错误。

      示例

      推荐

      删除第一个重载,因为它实在没什么意义;上面的函数可以使用1个或0个必须参数调用,因为函数可以安全地忽略额外的参数。

      1. declare function func(callback: (arg: number) => void): any;
      2. func(c => { });
      3. func(() => { });

      或者,你可以给callback的参数指定一个明确的类型:

      1. func((c:number) => { });

      逗号操作符使用在无副作用的表达式里时会被标记成错误

      大多数情况下,这种在之前是有效的逗号表达式现在是错误。

      示例

      1. let x = Math.pow((3, 5)); // x = NaN, was meant to be `Math.pow(3, 5)`
      2. // This code does not do what it appears to!
      3. let arr = [];
      4. switch(arr.length) {
      5. case 0, 1:
      6. return 'zero or one';
      7. default:
      8. return 'more than one';
      9. }

      推荐

      --allowUnreachableCode会禁用产生警告在整个编译过程中。或者,你可以使用void操作符来镇压这个逗号表达式错误:

      • Node.firstChildNode.lastChildNode.nextSiblingNode.previousSiblingNode.parentElementNode.parentNode现在是Node | null而非Node

        推荐明确检查null或使用断言操作符(比如node.lastChild!)。